import * as THREE from '../../build/three.module.js';
import Stats from '../../jsm/libs/stats.module.js';

const objects = []; // 网格体数组

const scene = new THREE.Scene();

// 生成canvas贴图
const generateTexture = () => {
  const canvas = document.createElement('canvas');
  canvas.width = 256;
  canvas.height = 256;

  const ctx = canvas.getContext('2d');
  const img = ctx.getImageData(0, 0, canvas.width, canvas.height);

  let x = 0, y = 0;

  for(let i = 0, j = 0, l = img.data.length; i < l; i += 4, j += 1) {
    x = j % 256;
    y = x === 0 ? y + 1 : y;

    img.data[i] = 255;
    img.data[i + 1] = 255;
    img.data[i + 2] = 255;
    img.data[i + 3] = Math.floor( x ^ y );
  }

  ctx.putImageData(img, 0, 0);

  return canvas;
}
// 根据给入的几何体和材质，生成网格对象并加入场景
const addMesh = (gmt, mat) => {
  const mesh = new THREE.Mesh(gmt, mat);

  // 定位
  mesh.position.x = (objects.length % 4) * 200 - 400;
  mesh.position.z = Math.floor(objects.length / 4) * 200 - 200;

  // 随机旋转
  mesh.rotation.x = Math.random() * 200 - 100;
  mesh.rotation.y = Math.random() * 200 - 100;
  mesh.rotation.z = Math.random() * 200 - 100;

  objects.push(mesh);
  scene.add(mesh);
}

const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 2000);
camera.position.set(0, 200, 800);

// 网格辅助线
const helper = new THREE.GridHelper(1000, 40, 0x303030, 0x303030);
helper.position.y = -75;
scene.add(helper);

// 材质
const materials = [];
const texture = new THREE.Texture( generateTexture() );
texture.needsUpdate = true;

materials.push( new THREE.MeshLambertMaterial({ map: texture, transparent: true }) ); // 漫反射材质（贴图，透明度）
materials.push( new THREE.MeshLambertMaterial({ color: 0xdddddd }) ); // 漫反射材质（表面颜色）
materials.push( new THREE.MeshPhongMaterial({ color: 0xdddddd, specular: 0x009900, shininess: 30, flatShading: true }) ); // 高光材质（表面颜色，高光颜色，亮度，平面阴影）
materials.push( new THREE.MeshNormalMaterial() ); // 法线贴图材质
materials.push( new THREE.MeshBasicMaterial({ color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending }) ); // 基础材质（表面颜色，透明，叠加混合）
materials.push( new THREE.MeshLambertMaterial({ color: 0xdddddd }) ); // 漫反射材质（表面颜色）
materials.push( new THREE.MeshPhongMaterial({ color: 0xdddddd, specular: 0x009900, shininess: 30, map: texture, transparent: true }) ); // 高光材质（表面颜色，高光颜色，亮度，贴图，透明度）
materials.push( new THREE.MeshNormalMaterial({ flatShading: true }) ); // 法线贴图材质（平面阴影）
materials.push( new THREE.MeshBasicMaterial({ color: 0xffaa00, wireframe: true }) ); // 基础材质（表面颜色，线框）
materials.push( new THREE.MeshDepthMaterial() ); // 深度材质
materials.push( new THREE.MeshLambertMaterial({ color: 0x666666, emissive: 0xff0000 }) ); // 漫反射材质（表面颜色，发光）
materials.push( new THREE.MeshPhongMaterial({ color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, opacity: 0.9, transparent: true }) ); // 高光材质（表面颜色，高光颜色，发光颜色，亮度，不透明度，开启透明检测）
materials.push( new THREE.MeshBasicMaterial({ map: texture, transparent: true }) ); // 基础网格材质（贴图、透明度）

// 几何体
const geometry = new THREE.SphereBufferGeometry(70, 32, 16);

// 创建并添加网格对象
for(let i = 0; i < materials.length; i += 1) {
  addMesh(geometry, materials[i])
}

// 环境光
scene.add(new THREE.AmbientLight(0x111111));

// 平行光
const directionLight = new THREE.DirectionalLight(0xffffff, 0.125);
directionLight.position.x = Math.random() - 0.5;
directionLight.position.y = Math.random() - 0.5;
directionLight.position.z = Math.random() - 0.5;
directionLight.position.normalize();
scene.add(directionLight);

// 点光源
const pointLieght = new THREE.PointLight(0xffffff, 1);
pointLieght.add( new THREE.Mesh( new THREE.SphereBufferGeometry(4, 8, 8), new THREE.MeshBasicMaterial({ color: 0xffffff }) ) );
scene.add(pointLieght);

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

// 统计
const stats = new Stats();
document.body.appendChild(stats.dom);

// 事件处理函数
const handleWindowResize = () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);
}

// 事件监听
window.addEventListener('resize', handleWindowResize, false);

// 渲染函数
const render = () => {
  const timer = Date.now() * 0.0001;

  // 镜头绕中心旋转
  camera.position.x = Math.sin(timer) * 1000;
  camera.position.z = Math.cos(timer) * 1000;
  camera.lookAt(scene.position);

  // 网格体自旋转
  for(let i = 0; i < objects.length; i += 1) {
    const obj = objects[i];

    obj.rotation.x += 0.01;
    obj.rotation.y += 0.005;
  }

  // 发光材质亮度周期变化
  materials[materials.length - 2].emissive.setHSL(0.54, 1, 0.35 * (0.5 + 0.5 * Math.sin(35 * timer)));
  materials[materials.length - 3].emissive.setHSL(0.04, 1, 0.35 * (0.5 + 0.5 * Math.sin(35 * timer)));

  // 点光源周期运动
  pointLieght.position.x = Math.sin(timer * 7) * 300;
  pointLieght.position.y = Math.sin(timer * 5) * 400;
  pointLieght.position.z = Math.sin(timer * 3) * 300;

  renderer.render(scene, camera);
}

// 驱动函数
const animate = () => {
  requestAnimationFrame(animate)

  render();
  stats.update();
}
animate();